<template>
  <el-dialog
      v-model="visible"
      title="参数设置与预览"
      width="1400px"
      :close-on-click-modal="false"
      @close="handleClose"
      class="combination-edit-dialog"
  >
    <div v-if="combination" class="edit-preview-container">
      <!-- 左侧参数设置区域 -->
      <div class="params-section">
        <el-card class="params-card">
          <template #header>
            <div class="section-header">
              <span><el-icon><Setting /></el-icon> 参数设置</span>
              <div class="header-actions">
                <el-button size="small" @click="showPresetDialog = true">
                  <el-icon><Collection /></el-icon>
                  预设管理
                </el-button>
              </div>
            </div>
          </template>

          <div class="params-content">
            <!-- 组合信息 -->
            <div class="combination-info">
              <el-descriptions :column="1" border size="small">
                <el-descriptions-item label="数字人">
                  <span class="file-name" :title="combination.human.original_name">
                    {{ combination.human.original_name }}
                  </span>
                </el-descriptions-item>
                <el-descriptions-item label="背景">
                  <span class="file-name" :title="combination.background.original_name">
                    {{ combination.background.original_name }}
                  </span>
                </el-descriptions-item>
              </el-descriptions>
            </div>

            <!-- 快速预设 -->
            <div class="quick-presets" v-if="recentPresets.length > 0">
              <div class="preset-label">快速应用：</div>
              <div class="preset-buttons">
                <el-button
                    v-for="preset in recentPresets"
                    :key="preset.id"
                    size="small"
                    @click="applyPreset(preset)"
                >
                  {{ preset.name }}
                </el-button>
              </div>
            </div>

            <!-- 参数表单 -->
            <div class="params-form">
              <el-form :model="localParams" label-width="100px" size="small">
                <GlobalParams v-model="localParams" @change="onParamsChange" :compact="true" />

                <div class="output-name-section">
                  <el-form-item label="输出文件名">
                    <el-input
                        v-model="localParams.output_name"
                        placeholder="输出文件名"
                        @input="onParamsChange"
                    />
                  </el-form-item>
                </div>
              </el-form>
            </div>

            <!-- 操作按钮 -->
            <div class="params-actions">
              <el-button @click="saveAsPreset" size="small">
                <el-icon><Plus /></el-icon>
                保存为预设
              </el-button>
              <el-button @click="resetParams" size="small">
                <el-icon><Refresh /></el-icon>
                重置参数
              </el-button>
            </div>
          </div>
        </el-card>
      </div>

      <!-- 右侧预览区域 -->
      <div class="preview-section">
        <el-card class="preview-card">
          <template #header>
            <div class="section-header">
              <span><el-icon><View /></el-icon> 实时预览</span>
              <div class="header-actions">
                <el-button
                    size="small"
                    @click="regeneratePreview"
                    :loading="previewLoading"
                >
                  <el-icon><Refresh /></el-icon>
                  刷新预览
                </el-button>
              </div>
            </div>
          </template>

          <div class="preview-container" v-loading="previewLoading">
            <div v-if="previewUrl" class="preview-image-wrapper">
              <el-image
                  :src="previewUrl"
                  fit="contain"
                  class="preview-image"
                  @error="handlePreviewError"
              >
                <template #error>
                  <div class="preview-error">
                    <el-icon><Picture /></el-icon>
                    <p>预览加载失败</p>
                    <el-button size="small" @click="regeneratePreview">重试</el-button>
                  </div>
                </template>
              </el-image>

              <!-- 预览信息 -->
              <div class="preview-info">
                <el-tag size="small">
                  {{ localParams.canvas_width }} × {{ localParams.canvas_height }}
                </el-tag>
                <el-tag size="small" type="success">
                  {{ localParams.output_format?.toUpperCase() || 'MP4' }}
                </el-tag>
                <el-tag size="small" type="info">
                  人物: ×{{ localParams.video_scale }}
                </el-tag>
                <el-tag size="small" type="warning">
                  背景: ×{{ localParams.bg_scale }}
                </el-tag>
              </div>
            </div>

            <el-empty
                v-else
                description="暂无预览"
                :image-size="120"
            />
          </div>
        </el-card>
      </div>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleCancel">取消</el-button>
        <el-button type="success" @click="handleStartProcess" :loading="processing">
          <el-icon><VideoPlay /></el-icon>
          开始处理
        </el-button>
        <el-button type="primary" @click="handleConfirm">
          <el-icon><Check /></el-icon>
          保存参数
        </el-button>
      </div>
    </template>

    <!-- 预设管理对话框 -->
    <PresetManagerDialog
        v-model="showPresetDialog"
        @apply="applyPreset"
        @save="savePresetFromDialog"
    />

    <!-- 保存预设对话框 -->
    <SavePresetDialog
        v-model="showSavePresetDialog"
        :params="localParams"
        @save="handleSavePreset"
    />
  </el-dialog>
</template>

<script setup>
import { ref, watch, computed, nextTick, onBeforeUnmount } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import GlobalParams from './GlobalParams.vue'
import PresetManagerDialog from './PresetManagerDialog.vue'
import SavePresetDialog from './SavePresetDialog.vue'
import api, {basePythonURL2} from '@/api'

const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false
  },
  combination: {
    type: Object,
    default: null
  }
})

const emit = defineEmits(['update:modelValue', 'update', 'startProcess'])

// 计算属性
const visible = computed({
  get: () => props.modelValue,
  set: (value) => {
    emit('update:modelValue', value)
  }
})

// 响应式数据
const localParams = ref({})
const originalParams = ref({})
const previewUrl = ref('')
const currentPreviewId = ref(null)
const previewLoading = ref(false)
const processing = ref(false)
const showPresetDialog = ref(false)
const showSavePresetDialog = ref(false)
const recentPresets = ref([])
const isApplyingPreset = ref(false) // 防止预设应用时的递归更新

// 参数变化防抖
let previewTimer = null

// 监听combination变化
watch(() => props.combination, async (newVal) => {
  if (newVal && !isApplyingPreset.value) {
    isApplyingPreset.value = true

    await nextTick()

    localParams.value = {
      ...newVal.params,
      output_name: newVal.output_name
    }
    originalParams.value = JSON.parse(JSON.stringify(localParams.value))

    await nextTick()
    generatePreview()

    setTimeout(() => {
      isApplyingPreset.value = false
    }, 100)
  }
}, { immediate: true, deep: true })

// 监听弹窗显示状态
watch(visible, (newVal) => {
  if (newVal) {
    loadRecentPresets()
  } else {
    clearCurrentPreview()
  }
})

// 方法
const onParamsChange = () => {
  // 如果正在应用预设，不触发预览更新
  if (isApplyingPreset.value) return

  // 防抖生成预览
  clearTimeout(previewTimer)
  previewTimer = setTimeout(() => {
    generatePreview()
  }, 800)
}

const generatePreview = async () => {
  if (!props.combination) return

  previewLoading.value = true

  // 清除旧预览
  await clearCurrentPreview()

  try {
    const result = await api.generatePreview(
        props.combination.human.file_id,
        props.combination.background.file_id,
        localParams.value
    )

    if (result.success) {
      currentPreviewId.value = result.preview_id
      previewUrl.value = `${basePythonURL2}${result.preview_url}?t=${Date.now()}`
    } else {
      ElMessage.error('生成预览失败: ' + (result.message || '未知错误'))
    }
  } catch (error) {
    console.error('生成预览失败:', error)
    ElMessage.error('生成预览失败')
  } finally {
    previewLoading.value = false
  }
}

const regeneratePreview = () => {
  generatePreview()
}

const clearCurrentPreview = async () => {
  if (currentPreviewId.value) {
    try {
      await api.clearPreview(currentPreviewId.value)
    } catch (error) {
      console.error('清除预览失败:', error)
    }
    currentPreviewId.value = null
  }
  previewUrl.value = ''
}

const handlePreviewError = () => {
  console.error('预览图片加载失败')
}

const loadRecentPresets = async () => {
  try {
    const result = await api.getPresets()
    if (result.success) {
      // 取最近的5个预设
      recentPresets.value = result.presets.slice(0, 5)
    }
  } catch (error) {
    console.error('加载预设失败:', error)
  }
}

const applyPreset = async (preset) => {
  if (isApplyingPreset.value) return

  try {
    isApplyingPreset.value = true

    // 应用预设，但保留输出文件名
    const outputName = localParams.value.output_name

    // 使用nextTick确保在下一个tick中更新
    await nextTick()

    localParams.value = {
      ...preset,
      output_name: outputName
    }

    // 等待DOM更新后再生成预览
    await nextTick()
    generatePreview()

    ElMessage.success(`已应用预设: ${preset.name}`)
  } finally {
    // 延迟重置标志，确保所有更新都完成
    setTimeout(() => {
      isApplyingPreset.value = false
    }, 100)
  }
}

const saveAsPreset = () => {
  showSavePresetDialog.value = true
}

const savePresetFromDialog = (presetData) => {
  // 从预设管理对话框保存
  handleSavePreset(presetData)
}

const handleSavePreset = async (presetData) => {
  try {
    const data = {
      ...presetData,
      ...localParams.value
    }
    delete data.output_name // 预设不包含输出文件名

    const result = await api.savePreset(data)
    if (result.success) {
      ElMessage.success('预设保存成功')
      loadRecentPresets() // 刷新预设列表
    } else {
      ElMessage.error('预设保存失败: ' + (result.message || '未知错误'))
    }
  } catch (error) {
    console.error('保存预设失败:', error)
    ElMessage.error('保存预设失败')
  }
}

const resetParams = () => {
  ElMessageBox.confirm('确定要重置所有参数吗？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    localParams.value = JSON.parse(JSON.stringify(originalParams.value))
    generatePreview()
    ElMessage.success('参数已重置')
  }).catch(() => {})
}

const handleClose = () => {
  clearCurrentPreview()
  visible.value = false
}

const handleCancel = () => {
  // 检查是否有未保存的更改
  const hasChanges = JSON.stringify(localParams.value) !== JSON.stringify(originalParams.value)

  if (hasChanges) {
    ElMessageBox.confirm('有未保存的参数更改，确定要放弃吗？', '提示', {
      confirmButtonText: '放弃',
      cancelButtonText: '继续编辑',
      type: 'warning'
    }).then(() => {
      handleClose()
    }).catch(() => {})
  } else {
    handleClose()
  }
}

const handleConfirm = () => {
  // 保存参数更改
  emit('update', {
    params: { ...localParams.value },
    output_name: localParams.value.output_name
  })

  ElMessage.success('参数已保存')
  handleClose()
}

const handleStartProcess = async () => {
  processing.value = true

  try {
    // 先保存参数
    emit('update', {
      params: { ...localParams.value },
      output_name: localParams.value.output_name
    })

    // 开始处理
    emit('startProcess', props.combination)

    ElMessage.success('处理任务已提交')
    handleClose()
  } catch (error) {
    ElMessage.error('提交处理任务失败')
  } finally {
    processing.value = false
  }
}

// 清理
const cleanup = () => {
  clearTimeout(previewTimer)
  clearCurrentPreview()
}

// 组件卸载时清理
onBeforeUnmount(() => {
  cleanup()
})
</script>

<style lang="scss" scoped>
.combination-edit-dialog {
  ::v-deep(.el-dialog) {
    margin-top: 5vh !important;
    margin-bottom: 5vh !important;
    height: 90vh;

    .el-dialog__body {
      padding: 20px;
      height: calc(90vh - 120px);
      overflow: hidden;
    }

    .el-dialog__footer {
      padding: 15px 20px;
      border-top: 1px solid #ebeef5;
    }
  }
}

:deep(el-dialog) {
  margin: 1em auto 50px;
}

.edit-preview-container {
  display: flex;
  gap: 24px;
  height: 100%;
}

.params-section {
  flex: 0 0 630px; // 固定左侧宽度为600px
  min-width: 630px;
}

.preview-section {
  flex: 1;
  min-width: 500px;
}

.params-card,
.preview-card {
  height: 100%;

  ::v-deep(.el-card__header) {
    padding: 16px 20px;
    border-bottom: 1px solid #f0f2f5;
  }

  ::v-deep(.el-card__body) {
    height: calc(100% - 60px);
    padding: 0;
    overflow: hidden;
  }
}

.params-content {
  height: 100%;
  padding: 20px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;

  span {
    display: flex;
    align-items: center;
    gap: 8px;
    font-weight: 600;
    color: #303133;
  }

  .header-actions {
    display: flex;
    gap: 8px;
  }
}

.combination-info {
  .file-name {
    max-width: 300px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    display: inline-block;
  }
}

.quick-presets {
  padding: 16px;
  background: #f8f9fa;
  border-radius: 8px;
  border: 1px solid #ebeef5;

  .preset-label {
    font-size: 14px;
    color: #606266;
    margin-bottom: 10px;
    font-weight: 500;
  }

  .preset-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
  }
}

.params-form {
  flex: 1;

  ::v-deep(.el-form) {
    .el-form-item {
      margin-bottom: 16px;
    }

    .el-form-item__label {
      font-size: 14px;
      color: #606266;
      font-weight: 500;
    }

    .el-input-number,
    .el-select,
    .el-input {
      width: 100%;
    }

    .el-slider {
      margin-right: 20px;
    }
  }
}

.output-name-section {
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid #ebeef5;
}

.params-actions {
  padding-top: 16px;
  border-top: 1px solid #ebeef5;
  display: flex;
  gap: 10px;
  justify-content: center;
}

.preview-container {
  height: 100%;
  padding: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.preview-image-wrapper {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
}

.preview-image {
  max-width: 50%;
  max-height: calc(100% - 60px);
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);

  ::v-deep(.el-image__inner){
  height: auto !important;
}
}

.preview-error {
  padding: 40px;
  text-align: center;
  color: #909399;

  .el-icon {
    font-size: 48px;
    margin-bottom: 16px;
    color: #c0c4cc;
  }

  p {
    margin: 16px 0;
    font-size: 14px;
  }
}

.preview-info {
  margin-top: 16px;
  display: flex;
  justify-content: center;
  gap: 8px;
  flex-wrap: wrap;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

// 覆盖GlobalParams组件的样式
::v-deep(.global-params) {
  .param-section {
    margin-bottom: 20px;
    border: 1px solid #ebeef5;
    border-radius: 6px;
    padding: 16px;
    background: #fafafa;

    &:last-child {
      margin-bottom: 0;
    }
  }

  .section-title {
    margin: 0 0 16px 0;
    font-size: 15px;
    font-weight: 600;
    color: #303133;
    display: flex;
    align-items: center;
    gap: 6px;
    border-bottom: 1px solid #ebeef5;
    padding-bottom: 8px;
  }

  .size-presets {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid #ebeef5;

    .preset-label {
      font-size: 13px;
      margin-bottom: 8px;
    }
  }

  .quick-actions {
    justify-content: flex-start;
  }

  .el-form-item {
    margin-bottom: 14px;
  }

  .el-row {
    margin-bottom: 0;
  }
}

// 响应式设计
@media (max-width: 1400px) {
  .edit-preview-container {
    flex-direction: column;
    gap: 20px;
  }

  .params-section {
    flex: none;
    min-width: auto;
  }

  .preview-section {
    min-width: auto;
    height: 400px;
  }
}
</style>